{
 "cells": [
  {
   "cell_type": "code",
   "execution_count": 1,
   "id": "6d2e4af3",
   "metadata": {},
   "outputs": [],
   "source": [
    "# This is a sample Python script.\n",
    "import os\n",
    "import re\n",
    "from datetime import timedelta\n",
    "import pandas as pd\n",
    "\n",
    "HOUR = 60 * 60 * 1000\n",
    "MINUTE = 60 * 1000\n",
    "\n",
    "# 找rtc最相关的wakeup alarm\n",
    "#\n",
    "file_id = 1\n",
    "all_attri_num = pd.DataFrame()\n",
    "\n",
    "# 不同策略下的数据\n",
    "# 不同策略下的数据\n",
    "networks = [\"flight\",\"wifi\",\"lte\"]\n",
    "strategies_list = [\"fullAlign\",\"align\",\"paper\",\"origin\"]\n",
    "network_data = {\"flight\":{},\"wifi\":{},\"lte\":{}}\n",
    "for n in networks:\n",
    "    tmp = {}\n",
    "    for s in strategies_list:\n",
    "        tmp[s] = {\"rtc_alarm\": [], \"drain\": []}\n",
    "    network_data[n] = tmp\n",
    "\n",
    "stratgies = {\n",
    "    \"fullAlign\": {\"rtc_alarm\": [], \"drain\": []},\n",
    "    \"align\": {\"rtc_alarm\": [], \"drain\": []},\n",
    "    \"paper\": {\"rtc_alarm\": [], \"drain\": []},\n",
    "    \"origin\": {\"rtc_alarm\": [], \"drain\": []}\n",
    "}\n",
    "\n",
    "# 将时间字符串转换为毫秒\n",
    "def parse_time(time_str):\n",
    "    h_match = re.search(r'(?P<hour>\\d+)h\\d+', time_str)\n",
    "    m_match = re.search(r'(?P<minute>\\d+)m\\d+', time_str)\n",
    "    s_match = re.search(r'(?P<second>\\d+)s\\d+', time_str)\n",
    "    ms_match = re.search(r'(?P<millisecond>\\d+)ms', time_str)\n",
    "\n",
    "    h = int(h_match.group('hour')) if h_match else 0\n",
    "    m = int(m_match.group('minute')) if m_match else 0\n",
    "    s = int(s_match.group('second')) if s_match else 0\n",
    "    ms = int(ms_match.group('millisecond')) if ms_match else 0\n",
    "\n",
    "    total_ms = h * 60 * 60 * 1000 + m * 60 * 1000 + s * 1000 + ms\n",
    "    if total_ms == 0:\n",
    "        return None\n",
    "    else:\n",
    "        return total_ms\n",
    "\n",
    "def get_time(time_str):\n",
    "    h_match = re.search(r'(?P<hour>\\d+)h\\d+', time_str)\n",
    "    m_match = re.search(r'(?P<minute>\\d+)m\\d+', time_str)\n",
    "    s_match = re.search(r'(?P<second>\\d+)s\\d+', time_str)\n",
    "    ms_match = re.search(r'(?P<millisecond>\\d+)ms', time_str)\n",
    "\n",
    "    h = int(h_match.group('hour')) if h_match else 0\n",
    "    m = int(m_match.group('minute')) if m_match else 0\n",
    "    s = int(s_match.group('second')) if s_match else 0\n",
    "    ms = int(ms_match.group('millisecond')) if ms_match else 0\n",
    "\n",
    "\n",
    "    return timedelta(hours=int(h),minutes=int(m), seconds=int(s), milliseconds=int(ms))\n",
    "\n",
    "# 处理每一行数据\n",
    "def process_drain_line(line):\n",
    "    screen_off_time = None\n",
    "    screen_on_time = None\n",
    "    charge_on_screen = None\n",
    "\n",
    "    time = parse_time(line.split()[1])\n",
    "\n",
    "    charge_search = re.search(r'charge=(\\d+)', line)\n",
    "    if charge_search:\n",
    "        charge = int(charge_search.group(1))\n",
    "\n",
    "    if \"-screen\" in line and screen_off_time is None:\n",
    "        screen_off_time = time\n",
    "\n",
    "    if \"+screen\" in line:\n",
    "        screen_on_time = time\n",
    "        charge_on_screen = charge\n",
    "\n",
    "\n",
    "\n",
    "\n",
    "def parse_log_line(line):\n",
    "    line = line.lstrip()\n",
    "    match = re.search(r\"(\\d+ms).*?(wake_reason=0:\\\"\\d+ qpnp_rtc_alarm\\\"|\\\"\\*walarm\\*:|\\\"\\*alarm\\*:).*\",\n",
    "                      line)\n",
    "    if match:\n",
    "        return (get_time(line), match.group(2))\n",
    "\n",
    "    return None\n",
    "\n",
    "def parse_log(path):\n",
    "    f = open(path, encoding=\"utf-8\")\n",
    "    fileContent = f.readlines()\n",
    "    f.close()\n",
    "    return fileContent\n",
    "\n",
    "def parse_timestamp(timestamp_str):\n",
    "    m, s, ms = re.match(r\"\\+(\\d+)m(\\d+)s(\\d+)ms\", timestamp_str).groups()\n",
    "    return timedelta(minutes=int(m), seconds=int(s), milliseconds=int(ms))\n",
    "\n",
    "def is_less_than_half_second(t1, t2):\n",
    "    return abs(t1 - t2) < timedelta(seconds=0.5)\n",
    "\n",
    "def count_alarm_walarm(line):\n",
    "    alarm = 0\n",
    "    walarm = 0\n",
    "    line = line.lstrip()\n",
    "    if re.search(r':\"\\*walarm\\*:',line):\n",
    "        walarm = 1\n",
    "    if re.search(r':\"\\*alarm\\*:',line):\n",
    "        alarm = 1\n",
    "    return walarm,alarm\n",
    "\n",
    "def get_rtc_alarm_num(line):\n",
    "    match = re.search(r'.*qpnp_rtc_alarm:.*(\\d+)\\s*times', line)\n",
    "    if match:\n",
    "        qpnp_rtc_alarm = int(match.group(1))\n",
    "    return qpnp_rtc_alarm\n",
    "\n",
    "\n",
    "def count_event(content):\n",
    "    batteryContentFlag = False\n",
    "    batteryContentOutFlag = False\n",
    "\n",
    "    wakeupContentFlag = False\n",
    "    wakeupContentOutFlag = False\n",
    "    # qpnp_rtc_alarm出现wakelock为walarm或者alarm次数\n",
    "    walarm_rtc_count = 0\n",
    "    alarm_rtc_count = 0\n",
    "\n",
    "    # wakelock为walarm或者alarm次数\n",
    "    w_count = 0\n",
    "    a_count = 0\n",
    "\n",
    "    atc_drain = 0\n",
    "    duration = \"0\"\n",
    "    qpnp_rtc_alarm = 0\n",
    "    app_wakeup_alarm_num = 0\n",
    "\n",
    "    prev_timestamp = None\n",
    "\n",
    "    # 计算真实耗电相关变量\n",
    "    time = None\n",
    "    screen_off_time = None\n",
    "    screen_on_time = None\n",
    "    charge_start = None\n",
    "    charge_end = None\n",
    "    charge_time = None\n",
    "    charge_start_flag = False\n",
    "\n",
    "    # time pattern\n",
    "\n",
    "    app_wakeup_num = 0\n",
    "    app_wakeup = pd.DataFrame()\n",
    "\n",
    "    for line in content:\n",
    "        # Judge arrive batterystats paragraph\n",
    "        line = line.lstrip()\n",
    "        if not batteryContentFlag:\n",
    "            if re.search(r\"DUMP OF SERVICE batterystats:.*\", line):\n",
    "                batteryContentFlag = True\n",
    "\n",
    "        # Judge out batterystats paragraph\n",
    "        if (batteryContentOutFlag is False) and (batteryContentFlag is True):\n",
    "            if re.search(r\"Per-PID Stats:.*\", line):\n",
    "                batteryContentOutFlag = True\n",
    "                batteryContentFlag = False\n",
    "\n",
    "        # Judge arrive app status\n",
    "        if (batteryContentOutFlag is True) and (wakeupContentFlag is False):\n",
    "            if re.search(\"Resource Power Manager Stats\", line):\n",
    "                wakeupContentFlag = True\n",
    "\n",
    "        # Judge out app status\n",
    "        if (wakeupContentOutFlag is False) and (wakeupContentFlag is True):\n",
    "            if re.search(\"Total cpu time reads: \", line):\n",
    "                wakeupContentFlag = False\n",
    "                wakeupContentOutFlag = True\n",
    "\n",
    "\n",
    "\n",
    "        if batteryContentFlag:\n",
    "            if line.split():\n",
    "                tmp = parse_time(line.split()[0])\n",
    "                if tmp is not None:\n",
    "                    time = tmp\n",
    "\n",
    "            # 计算真实耗电量\n",
    "            charge_search = re.search(r'charge=(\\d+)', line)\n",
    "            if charge_search:\n",
    "                charge = int(charge_search.group(1))\n",
    "                charge_time = time\n",
    "                if charge_time is not None and charge_time > 3 * HOUR + 59 * MINUTE:\n",
    "                    screen_on_time = charge_time\n",
    "                    charge_end = charge\n",
    "                    batteryContentFlag = False\n",
    "                    batteryContentOutFlag = True\n",
    "\n",
    "            # 当灭屏后，flag标志位置为true，记录第一个charge\n",
    "            if charge_start_flag:\n",
    "                charge_start_flag = False\n",
    "                charge_start = charge\n",
    "\n",
    "            if \"-screen\" in line and screen_off_time is None:\n",
    "                screen_off_time = time\n",
    "                charge_start_flag = True\n",
    "\n",
    "\n",
    "\n",
    "            # 统计qpnp_rtc_alarm\n",
    "            parsed_line = parse_log_line(line)\n",
    "\n",
    "\n",
    "            m,n=count_alarm_walarm(line)\n",
    "            w_count += m\n",
    "            a_count += n\n",
    "            if parsed_line is None:\n",
    "                # 匹配qpnp_rtc_alarm\n",
    "                rtc_match = re.search(r'qpnp_rtc_alarm:.*\\((\\d+) times\\)', line)\n",
    "                if rtc_match:\n",
    "                    qpnp_rtc_alarm = int(rtc_match.group(1))\n",
    "\n",
    "\n",
    "                # 匹配actual drain\n",
    "                # Match the actual drain numbers and calculate the average\n",
    "                drain_match = re.search(r'actual drain: (\\d+\\.?\\d*)-(\\d+\\.?\\d*)', line)\n",
    "                if drain_match:\n",
    "                    num1 = float(drain_match.group(1))\n",
    "                    num2 = float(drain_match.group(2))\n",
    "                    atc_drain = (num1 + num2) / 2\n",
    "\n",
    "                # Match the durations\n",
    "                duration_matches = re.search(r'idle:.*duration: ([\\dhms\\. ]+)', line)\n",
    "                if duration_matches:\n",
    "                    duration = duration_matches.group(1)\n",
    "                continue\n",
    "\n",
    "\n",
    "            timestamp, event = parsed_line\n",
    "\n",
    "            if 'wake_reason=0:\"546 qpnp_rtc_alarm\"' in event:\n",
    "                prev_timestamp = timestamp\n",
    "            elif prev_timestamp is not None and '*walarm*:' in event and abs(prev_timestamp - timestamp) < timedelta(\n",
    "                    seconds=0.5):\n",
    "                walarm_rtc_count += 1\n",
    "                prev_timestamp = None\n",
    "            elif prev_timestamp is not None and '*alarm*:' in event and abs(prev_timestamp - timestamp) < timedelta(\n",
    "                    seconds=0.5):\n",
    "                alarm_rtc_count += 1\n",
    "                prev_timestamp = None\n",
    "\n",
    "        if wakeupContentFlag:\n",
    "            # 统计App wakeup alarm\n",
    "            # if \"Wakeup alarm *walarm*:\" in line:\n",
    "\n",
    "            # 根据apk名称统计\n",
    "            app_name_pattern = re.search(r'Apk\\s(.+?):',line)\n",
    "            if app_name_pattern:\n",
    "                if app_wakeup_num != 0:\n",
    "                    app_wakeup[app_name] = attri_num\n",
    "                app_wakeup_num = 0\n",
    "                app_name = app_name_pattern.group(1)\n",
    "            s_app_wakeup = re.search(r'Wakeup alarm \\*walarm\\*:(.+?):\\s(\\d+)\\s+times', line)\n",
    "            if s_app_wakeup:\n",
    "                attri = s_app_wakeup.group((1))\n",
    "                attri_num = int(s_app_wakeup.group((2)))\n",
    "                app_wakeup_alarm_num += attri_num\n",
    "                app_wakeup_num += attri_num\n",
    "        if wakeupContentOutFlag :\n",
    "            if app_wakeup_num != 0:\n",
    "                app_wakeup[app_name] = attri_num\n",
    "            break\n",
    "\n",
    "\n",
    "            # TODO:统计不同应用的waekup alarm，找到与qpnp_rtc_alarm关系最大的那个\n",
    "\n",
    "    print(\"App wakeup alarm：\"+str(app_wakeup_alarm_num))\n",
    "\n",
    "    # 增加属性\n",
    "    app_wakeup[\"wakeup_alarm\"] = app_wakeup_alarm_num\n",
    "    app_wakeup[\"qpnp_rtc_alarm\"] = qpnp_rtc_alarm\n",
    "\n",
    "    # 将文件中的wakeup数量增加到全局变量中\n",
    "    global all_attri_num\n",
    "    all_attri_num = pd.concat([all_attri_num, app_wakeup], axis=0, ignore_index=True)\n",
    "\n",
    "    if charge_end == None:\n",
    "        charge_end = charge\n",
    "    if screen_on_time == None:\n",
    "        screen_on_time = charge_time\n",
    "    if screen_off_time is None:\n",
    "        total_hour = screen_on_time / (60 * 60 * 1000)\n",
    "    else:\n",
    "        total_hour = (screen_on_time - screen_off_time) / (60 * 60 * 1000)\n",
    "    total_drain = charge_start - charge_end\n",
    "    avg_drain = total_drain / total_hour\n",
    "    return walarm_rtc_count + alarm_rtc_count, w_count + a_count,qpnp_rtc_alarm,atc_drain,duration,avg_drain,total_hour\n",
    "\n",
    "\n",
    "def print_hi(name):\n",
    "    # Use a breakpoint in the code line below to debug your script.\n",
    "    print(f'Hi, {name}')  # Press Ctrl+F8 to toggle the breakpoint.\n",
    "\n",
    "def count_Walarm_Qpnp(path):\n",
    "    fileContent = parse_log(path)\n",
    "    walarm_alarm_rtc_count,w_a_count,rtc_count,actual_drain,duration,avg_drain,test_time = count_event(fileContent)\n",
    "    print(\"test duration:\" + duration)\n",
    "    print(\"test time:\" + str(test_time)+\"h\")\n",
    "    # print(\"qpnp_rtc_alarm:\" + str(rtc_count))\n",
    "    # print(\"actual drain:\" + f\"{actual_drain:.2f}\")\n",
    "    print(\"walarm&rtc_alarm Count+alarm&rtc_alarm Count:\" + str(walarm_alarm_rtc_count) )\n",
    "    print(\"alarm Count + walarm Count:\" + str(w_a_count))\n",
    "    print(\"average drain:\" + f\"{avg_drain:.2f}\"+\"\\n\")\n",
    "    \n",
    "    if test_time < 3.9:\n",
    "        return None,None\n",
    "    return walarm_alarm_rtc_count, avg_drain\n"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 2,
   "id": "322f1b29",
   "metadata": {
    "scrolled": true
   },
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "fullAlign\n",
      "device3_0707_1.txt: \n",
      "App wakeup alarm：268\n",
      "test duration:0\n",
      "test time:4.0001058333333335h\n",
      "walarm&rtc_alarm Count+alarm&rtc_alarm Count:23\n",
      "alarm Count + walarm Count:83\n",
      "average drain:26.50\n",
      "\n",
      "device3_0704_1.txt: \n",
      "App wakeup alarm：307\n",
      "test duration:0\n",
      "test time:4.000078611111111h\n",
      "walarm&rtc_alarm Count+alarm&rtc_alarm Count:26\n",
      "alarm Count + walarm Count:118\n",
      "average drain:31.00\n",
      "\n",
      "device1_0706_1.txt: \n",
      "App wakeup alarm：201\n",
      "test duration:0\n",
      "test time:3.999950277777778h\n",
      "walarm&rtc_alarm Count+alarm&rtc_alarm Count:19\n",
      "alarm Count + walarm Count:46\n",
      "average drain:32.75\n",
      "\n",
      "device2_0707_1.txt: \n",
      "App wakeup alarm：276\n",
      "test duration:0\n",
      "test time:4.0001452777777775h\n",
      "walarm&rtc_alarm Count+alarm&rtc_alarm Count:36\n",
      "alarm Count + walarm Count:104\n",
      "average drain:34.75\n",
      "\n",
      "device2_0706_1.txt: \n",
      "App wakeup alarm：160\n",
      "test duration:0\n",
      "test time:3.999652777777778h\n",
      "walarm&rtc_alarm Count+alarm&rtc_alarm Count:23\n",
      "alarm Count + walarm Count:65\n",
      "average drain:31.00\n",
      "\n",
      "device2_0704_1.txt: \n",
      "App wakeup alarm：193\n",
      "test duration:0\n",
      "test time:3.9996633333333333h\n",
      "walarm&rtc_alarm Count+alarm&rtc_alarm Count:39\n",
      "alarm Count + walarm Count:84\n",
      "average drain:31.75\n",
      "\n",
      "device1_0707_1.txt: \n",
      "App wakeup alarm：187\n",
      "test duration:0\n",
      "test time:3.9999486111111113h\n",
      "walarm&rtc_alarm Count+alarm&rtc_alarm Count:18\n",
      "alarm Count + walarm Count:44\n",
      "average drain:31.50\n",
      "\n",
      "device3_0706_1.txt: \n",
      "App wakeup alarm：286\n",
      "test duration:0\n",
      "test time:4.000033888888889h\n",
      "walarm&rtc_alarm Count+alarm&rtc_alarm Count:30\n",
      "alarm Count + walarm Count:85\n",
      "average drain:28.25\n",
      "\n",
      "device1_0704_1.txt: \n",
      "App wakeup alarm：187\n",
      "test duration:0\n",
      "test time:3.9999016666666667h\n",
      "walarm&rtc_alarm Count+alarm&rtc_alarm Count:17\n",
      "alarm Count + walarm Count:34\n",
      "average drain:37.00\n",
      "\n",
      "align\n",
      "paper\n",
      "origin\n",
      "device1_0630_1.txt: \n",
      "App wakeup alarm：178\n",
      "test duration:0\n",
      "test time:3.999805h\n",
      "walarm&rtc_alarm Count+alarm&rtc_alarm Count:15\n",
      "alarm Count + walarm Count:35\n",
      "average drain:37.00\n",
      "\n",
      "device3_0710_1.txt: \n",
      "App wakeup alarm：251\n",
      "test duration:0\n",
      "test time:4.000060277777778h\n",
      "walarm&rtc_alarm Count+alarm&rtc_alarm Count:56\n",
      "alarm Count + walarm Count:90\n",
      "average drain:28.75\n",
      "\n",
      "device2_0630_1.txt: \n",
      "App wakeup alarm：216\n",
      "test duration:0\n",
      "test time:3.9999458333333333h\n",
      "walarm&rtc_alarm Count+alarm&rtc_alarm Count:29\n",
      "alarm Count + walarm Count:60\n",
      "average drain:35.25\n",
      "\n",
      "device1_0705_1.txt: \n",
      "App wakeup alarm：153\n",
      "test duration:0\n",
      "test time:3.9999933333333333h\n",
      "walarm&rtc_alarm Count+alarm&rtc_alarm Count:13\n",
      "alarm Count + walarm Count:25\n",
      "average drain:34.50\n",
      "\n",
      "device2_0705_1.txt: \n",
      "App wakeup alarm：226\n",
      "test duration:0\n",
      "test time:4.0000752777777775h\n",
      "walarm&rtc_alarm Count+alarm&rtc_alarm Count:48\n",
      "alarm Count + walarm Count:66\n",
      "average drain:32.00\n",
      "\n",
      "device3_0630_1.txt: \n",
      "App wakeup alarm：321\n",
      "test duration:0\n",
      "test time:3.9999977777777778h\n",
      "walarm&rtc_alarm Count+alarm&rtc_alarm Count:28\n",
      "alarm Count + walarm Count:82\n",
      "average drain:29.50\n",
      "\n",
      "device3_0705_1.txt: \n",
      "App wakeup alarm：306\n",
      "test duration:0\n",
      "test time:3.99991h\n",
      "walarm&rtc_alarm Count+alarm&rtc_alarm Count:29\n",
      "alarm Count + walarm Count:90\n",
      "average drain:27.75\n",
      "\n",
      "device1_0710_1.txt: \n",
      "App wakeup alarm：183\n",
      "test duration:0\n",
      "test time:4.000013333333333h\n",
      "walarm&rtc_alarm Count+alarm&rtc_alarm Count:24\n",
      "alarm Count + walarm Count:48\n",
      "average drain:33.50\n",
      "\n",
      "device2_0710_1.txt: \n",
      "App wakeup alarm：244\n",
      "test duration:0\n",
      "test time:4.000014722222223h\n",
      "walarm&rtc_alarm Count+alarm&rtc_alarm Count:37\n",
      "alarm Count + walarm Count:69\n",
      "average drain:33.00\n",
      "\n",
      "fullAlign\n",
      "device3_0707_1.txt: \n",
      "App wakeup alarm：15\n",
      "test duration:0\n",
      "test time:3.1781516666666665h\n",
      "walarm&rtc_alarm Count+alarm&rtc_alarm Count:46\n",
      "alarm Count + walarm Count:111\n",
      "average drain:49.40\n",
      "\n",
      "device3_0704_1.txt: \n",
      "App wakeup alarm：234\n",
      "test duration:0\n",
      "test time:3.9997005555555556h\n",
      "walarm&rtc_alarm Count+alarm&rtc_alarm Count:39\n",
      "alarm Count + walarm Count:123\n",
      "average drain:38.25\n",
      "\n",
      "device2_0707_1.txt: \n",
      "App wakeup alarm：276\n",
      "test duration:0\n",
      "test time:3.985857777777778h\n",
      "walarm&rtc_alarm Count+alarm&rtc_alarm Count:46\n",
      "alarm Count + walarm Count:141\n",
      "average drain:42.65\n",
      "\n",
      "device2_0706_1.txt: \n",
      "App wakeup alarm：242\n",
      "test duration:0\n",
      "test time:3.999718611111111h\n",
      "walarm&rtc_alarm Count+alarm&rtc_alarm Count:45\n",
      "alarm Count + walarm Count:145\n",
      "average drain:40.00\n",
      "\n",
      "device2_0704_1.txt: \n",
      "App wakeup alarm：224\n",
      "test duration:0\n",
      "test time:3.999661388888889h\n",
      "walarm&rtc_alarm Count+alarm&rtc_alarm Count:59\n",
      "alarm Count + walarm Count:113\n",
      "average drain:39.50\n",
      "\n",
      "device1_0707_1.txt: \n",
      "App wakeup alarm：12\n",
      "test duration:0\n",
      "test time:2.7647708333333334h\n",
      "walarm&rtc_alarm Count+alarm&rtc_alarm Count:17\n",
      "alarm Count + walarm Count:47\n",
      "average drain:78.49\n",
      "\n",
      "device1_0704_1.txt: \n",
      "App wakeup alarm：143\n",
      "test duration:0\n",
      "test time:3.9879630555555554h\n",
      "walarm&rtc_alarm Count+alarm&rtc_alarm Count:18\n",
      "alarm Count + walarm Count:51\n",
      "average drain:42.88\n",
      "\n",
      "align\n",
      "paper\n",
      "origin\n",
      "device3_0710_1.txt: \n",
      "App wakeup alarm：269\n",
      "test duration:0\n",
      "test time:3.9997430555555558h\n",
      "walarm&rtc_alarm Count+alarm&rtc_alarm Count:85\n",
      "alarm Count + walarm Count:157\n",
      "average drain:38.75\n",
      "\n",
      "device3_0703_1.txt: \n",
      "App wakeup alarm：276\n",
      "test duration:0\n",
      "test time:4.000093611111111h\n",
      "walarm&rtc_alarm Count+alarm&rtc_alarm Count:54\n",
      "alarm Count + walarm Count:123\n",
      "average drain:37.25\n",
      "\n",
      "device1_0705_1.txt: \n",
      "App wakeup alarm：152\n",
      "test duration:0\n",
      "test time:3.9998008333333335h\n",
      "walarm&rtc_alarm Count+alarm&rtc_alarm Count:51\n",
      "alarm Count + walarm Count:97\n",
      "average drain:41.50\n",
      "\n",
      "device2_0703_1.txt: \n",
      "App wakeup alarm：280\n",
      "test duration:0\n",
      "test time:3.9974761111111112h\n",
      "walarm&rtc_alarm Count+alarm&rtc_alarm Count:42\n",
      "alarm Count + walarm Count:147\n",
      "average drain:43.28\n",
      "\n",
      "device2_0705_1.txt: \n",
      "App wakeup alarm：171\n",
      "test duration:0\n",
      "test time:4.000073333333333h\n",
      "walarm&rtc_alarm Count+alarm&rtc_alarm Count:64\n",
      "alarm Count + walarm Count:111\n",
      "average drain:37.75\n",
      "\n",
      "device3_0705_1.txt: \n",
      "App wakeup alarm：30\n",
      "test duration:0\n",
      "test time:3.200094722222222h\n",
      "walarm&rtc_alarm Count+alarm&rtc_alarm Count:46\n",
      "alarm Count + walarm Count:112\n",
      "average drain:49.37\n",
      "\n",
      "device1_0710_1.txt: \n",
      "App wakeup alarm：109\n",
      "test duration:0\n",
      "test time:3.999852222222222h\n",
      "walarm&rtc_alarm Count+alarm&rtc_alarm Count:40\n",
      "alarm Count + walarm Count:79\n",
      "average drain:45.25\n",
      "\n",
      "device1_0711_1.txt: \n",
      "App wakeup alarm：172\n",
      "test duration:0\n",
      "test time:4.000083333333333h\n",
      "walarm&rtc_alarm Count+alarm&rtc_alarm Count:49\n",
      "alarm Count + walarm Count:106\n",
      "average drain:48.75\n",
      "\n",
      "device3_0711_1.txt: \n",
      "App wakeup alarm：221\n",
      "test duration:0\n",
      "test time:4.000141666666667h\n",
      "walarm&rtc_alarm Count+alarm&rtc_alarm Count:88\n",
      "alarm Count + walarm Count:148\n",
      "average drain:37.25\n",
      "\n",
      "device2_0711_1.txt: \n",
      "App wakeup alarm：195\n",
      "test duration:0\n",
      "test time:4.000053333333334h\n",
      "walarm&rtc_alarm Count+alarm&rtc_alarm Count:68\n",
      "alarm Count + walarm Count:122\n",
      "average drain:40.75\n",
      "\n",
      "device2_0710_1.txt: \n",
      "App wakeup alarm：182\n",
      "test duration:0\n",
      "test time:3.9998808333333336h\n",
      "walarm&rtc_alarm Count+alarm&rtc_alarm Count:48\n",
      "alarm Count + walarm Count:117\n",
      "average drain:43.50\n",
      "\n",
      "device1_0703_1.txt: \n",
      "App wakeup alarm：512\n",
      "test duration:0\n",
      "test time:1.9759338888888889h\n",
      "walarm&rtc_alarm Count+alarm&rtc_alarm Count:0\n",
      "alarm Count + walarm Count:4\n",
      "average drain:33.40\n",
      "\n",
      "fullAlign\n",
      "device3_0704_1.txt: \n",
      "App wakeup alarm：203\n",
      "test duration:0\n",
      "test time:3.9969455555555555h\n",
      "walarm&rtc_alarm Count+alarm&rtc_alarm Count:38\n",
      "alarm Count + walarm Count:94\n",
      "average drain:55.79\n",
      "\n",
      "device1_0706_1.txt: \n",
      "App wakeup alarm：118\n",
      "test duration:0\n",
      "test time:2.1281605555555556h\n",
      "walarm&rtc_alarm Count+alarm&rtc_alarm Count:6\n",
      "alarm Count + walarm Count:37\n",
      "average drain:96.80\n",
      "\n",
      "device2_0706_1.txt: \n",
      "App wakeup alarm：127\n",
      "test duration:0\n",
      "test time:4.000001388888889h\n",
      "walarm&rtc_alarm Count+alarm&rtc_alarm Count:33\n",
      "alarm Count + walarm Count:83\n",
      "average drain:53.25\n",
      "\n",
      "device2_0704_1.txt: \n",
      "App wakeup alarm：196\n",
      "test duration:0\n",
      "test time:3.999746111111111h\n",
      "walarm&rtc_alarm Count+alarm&rtc_alarm Count:31\n",
      "alarm Count + walarm Count:90\n",
      "average drain:54.50\n",
      "\n",
      "device3_0706_1.txt: \n",
      "App wakeup alarm：218\n",
      "test duration:0\n",
      "test time:3.9996744444444445h\n",
      "walarm&rtc_alarm Count+alarm&rtc_alarm Count:32\n",
      "alarm Count + walarm Count:98\n",
      "average drain:57.50\n",
      "\n",
      "device1_0704_1.txt: \n",
      "App wakeup alarm：319\n",
      "test duration:0\n",
      "test time:3.946828611111111h\n",
      "walarm&rtc_alarm Count+alarm&rtc_alarm Count:32\n",
      "alarm Count + walarm Count:49\n",
      "average drain:43.33\n",
      "\n",
      "align\n",
      "paper\n",
      "origin\n",
      "device3_0710_1.txt: \n",
      "App wakeup alarm：189\n",
      "test duration:0\n",
      "test time:4.000095h\n",
      "walarm&rtc_alarm Count+alarm&rtc_alarm Count:70\n",
      "alarm Count + walarm Count:124\n",
      "average drain:44.00\n",
      "\n",
      "device3_0703_1.txt: \n"
     ]
    },
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "App wakeup alarm：256\n",
      "test duration:0\n",
      "test time:3.999941111111111h\n",
      "walarm&rtc_alarm Count+alarm&rtc_alarm Count:30\n",
      "alarm Count + walarm Count:117\n",
      "average drain:58.00\n",
      "\n",
      "device1_0705_1.txt: \n",
      "App wakeup alarm：149\n",
      "test duration:0\n",
      "test time:3.9995516666666666h\n",
      "walarm&rtc_alarm Count+alarm&rtc_alarm Count:35\n",
      "alarm Count + walarm Count:103\n",
      "average drain:63.01\n",
      "\n",
      "device2_0703_1.txt: \n",
      "App wakeup alarm：187\n",
      "test duration:0\n",
      "test time:3.9996722222222223h\n",
      "walarm&rtc_alarm Count+alarm&rtc_alarm Count:41\n",
      "alarm Count + walarm Count:84\n",
      "average drain:51.25\n",
      "\n",
      "device2_0705_1.txt: \n",
      "App wakeup alarm：176\n",
      "test duration:0\n",
      "test time:4.000035277777778h\n",
      "walarm&rtc_alarm Count+alarm&rtc_alarm Count:44\n",
      "alarm Count + walarm Count:112\n",
      "average drain:51.75\n",
      "\n",
      "device3_0705_1.txt: \n",
      "App wakeup alarm：256\n",
      "test duration:0\n",
      "test time:3.9995619444444444h\n",
      "walarm&rtc_alarm Count+alarm&rtc_alarm Count:35\n",
      "alarm Count + walarm Count:101\n",
      "average drain:50.51\n",
      "\n",
      "device1_0710_1.txt: \n",
      "App wakeup alarm：144\n",
      "test duration:0\n",
      "test time:3.9464983333333334h\n",
      "walarm&rtc_alarm Count+alarm&rtc_alarm Count:43\n",
      "alarm Count + walarm Count:105\n",
      "average drain:62.08\n",
      "\n",
      "device2_0710_1.txt: \n",
      "App wakeup alarm：126\n",
      "test duration:0\n",
      "test time:3.9838722222222223h\n",
      "walarm&rtc_alarm Count+alarm&rtc_alarm Count:41\n",
      "alarm Count + walarm Count:90\n",
      "average drain:55.72\n",
      "\n",
      "device1_0703_1.txt: \n",
      "App wakeup alarm：140\n",
      "test duration:0\n",
      "test time:3.9979086111111113h\n",
      "walarm&rtc_alarm Count+alarm&rtc_alarm Count:24\n",
      "alarm Count + walarm Count:55\n",
      "average drain:60.53\n",
      "\n"
     ]
    }
   ],
   "source": [
    "# 可选参数flight 、 wifi 、lte\n",
    "for network_pattern in networks:\n",
    "    # fullAlign对应完整的预测模块，align对应部分预测模块，paper对应对比论文，origin对应原生\n",
    "    data_path = \"../batteryStats/oppo/v0.1/batch\"\n",
    "\n",
    "    # 将batterystats的txt文件放入下列路径中\n",
    "    fullAlign_path = os.path.join(data_path, network_pattern, strategies_list[0])\n",
    "    align_path = os.path.join(data_path, network_pattern, strategies_list[1])\n",
    "    paper_path = os.path.join(data_path, network_pattern, strategies_list[2])\n",
    "    origin_path = os.path.join(data_path, network_pattern, strategies_list[3])\n",
    "    # align_path = \"batteryStats/align\"\n",
    "    # origin_path = \"batteryStats/origin\"\n",
    "\n",
    "    strtegies_path = [fullAlign_path,align_path,paper_path,origin_path]\n",
    "\n",
    "\n",
    "\n",
    "    for i in range(len(strategies_list)):\n",
    "        print(strategies_list[i])\n",
    "        for file_name in os.listdir(strtegies_path[i]):\n",
    "            print(file_name + \": \")\n",
    "            rtc_alarm,drain=count_Walarm_Qpnp(os.path.join(strtegies_path[i], file_name))\n",
    "            # 添加数据\n",
    "            if rtc_alarm == None or drain == None:\n",
    "                    continue\n",
    "            network_data.get(network_pattern).get(strategies_list[i]).get(\"rtc_alarm\").append(rtc_alarm)\n",
    "            network_data.get(network_pattern).get(strategies_list[i]).get(\"drain\").append(drain)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 3,
   "id": "608fbe7c",
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "{'flight': {'fullAlign': {'rtc_alarm': [23, 26, 19, 36, 23, 39, 18, 30, 17],\n",
       "   'drain': [26.499298872717326,\n",
       "    30.999390775861833,\n",
       "    32.750407105754995,\n",
       "    34.748737945142686,\n",
       "    31.002691205833838,\n",
       "    31.752672516603482,\n",
       "    31.500404692699174,\n",
       "    28.24976066174995,\n",
       "    37.000909605694474]},\n",
       "  'align': {'rtc_alarm': [], 'drain': []},\n",
       "  'paper': {'rtc_alarm': [], 'drain': []},\n",
       "  'origin': {'rtc_alarm': [15, 56, 29, 13, 48, 28, 29, 24, 37],\n",
       "   'drain': [37.0018038379371,\n",
       "    28.749566760000906,\n",
       "    35.25047735021412,\n",
       "    34.500057500095835,\n",
       "    31.999397789111054,\n",
       "    29.500016388897993,\n",
       "    27.750624389048756,\n",
       "    33.499888333705556,\n",
       "    32.9998785421137]}},\n",
       " 'wifi': {'fullAlign': {'rtc_alarm': [39, 46, 45, 59, 18],\n",
       "   'drain': [38.25286365187616,\n",
       "    42.650794252568524,\n",
       "    40.002814086852084,\n",
       "    39.50334406780685,\n",
       "    42.87903313491913]},\n",
       "  'align': {'rtc_alarm': [], 'drain': []},\n",
       "  'paper': {'rtc_alarm': [], 'drain': []},\n",
       "  'origin': {'rtc_alarm': [85, 54, 51, 42, 64, 40, 49, 88, 68, 48],\n",
       "   'drain': [38.752489309209096,\n",
       "    37.24912826692876,\n",
       "    41.50206645705901,\n",
       "    43.277306778429775,\n",
       "    37.749307929354636,\n",
       "    45.25167179787476,\n",
       "    48.74898439615841,\n",
       "    37.248680775889184,\n",
       "    40.74945667391101,\n",
       "    43.50129597610928]}},\n",
       " 'lte': {'fullAlign': {'rtc_alarm': [38, 33, 31, 32, 32],\n",
       "   'drain': [55.79260385221937,\n",
       "    53.24998151042308,\n",
       "    54.503459455690454,\n",
       "    57.50468024203081,\n",
       "    43.325924900463335]},\n",
       "  'align': {'rtc_alarm': [], 'drain': []},\n",
       "  'paper': {'rtc_alarm': [], 'drain': []},\n",
       "  'origin': {'rtc_alarm': [70, 30, 35, 41, 44, 35, 43, 41, 24],\n",
       "   'drain': [43.99895502481816,\n",
       "    58.00085390146022,\n",
       "    63.007062041537154,\n",
       "    51.254199996944195,\n",
       "    51.74954359777521,\n",
       "    50.505531057116464,\n",
       "    62.080350555492444,\n",
       "    55.72467880914297,\n",
       "    60.53164880443393]}}}"
      ]
     },
     "execution_count": 3,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "network_data"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 4,
   "id": "0a3c68a4",
   "metadata": {},
   "outputs": [
    {
     "data": {
      "image/png": "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",
      "text/plain": [
       "<Figure size 640x480 with 6 Axes>"
      ]
     },
     "metadata": {},
     "output_type": "display_data"
    }
   ],
   "source": [
    "import matplotlib.pyplot as plt\n",
    "\n",
    "attri = [\"rtc_alarm\",\"drain\"]\n",
    "\n",
    "# 创建一个2行2列的子图\n",
    "fig, axs = plt.subplots(2, 3)\n",
    "\n",
    "for i in range(len(attri)):\n",
    "    for j in range(len(networks)):\n",
    "        axs[i,j].boxplot([network_data.get(networks[j]).get(strategies_list[0]).get(attri[i]),\n",
    "                     network_data.get(networks[j]).get(strategies_list[3]).get(attri[i])],showmeans=True,meanline=True)\n",
    "        axs[i,j].set_xticklabels([strategies_list[0], strategies_list[3]])\n",
    "        axs[i,j].set_title(networks[j]+\" \"+attri[i])\n",
    "\n",
    "# 调整子图之间的垂直间距\n",
    "plt.subplots_adjust(hspace=0.5)\n",
    "# 显示图形\n",
    "plt.show()"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 5,
   "id": "bb2be53a",
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "{'flight': {'fullAlign': {'rtc_alarm': [23, 26, 19, 36, 23, 39, 18, 30, 17],\n",
       "   'drain': [26.499298872717326,\n",
       "    30.999390775861833,\n",
       "    32.750407105754995,\n",
       "    34.748737945142686,\n",
       "    31.002691205833838,\n",
       "    31.752672516603482,\n",
       "    31.500404692699174,\n",
       "    28.24976066174995,\n",
       "    37.000909605694474]},\n",
       "  'align': {'rtc_alarm': [], 'drain': []},\n",
       "  'paper': {'rtc_alarm': [], 'drain': []},\n",
       "  'origin': {'rtc_alarm': [15, 56, 29, 13, 48, 28, 29, 24, 37],\n",
       "   'drain': [37.0018038379371,\n",
       "    28.749566760000906,\n",
       "    35.25047735021412,\n",
       "    34.500057500095835,\n",
       "    31.999397789111054,\n",
       "    29.500016388897993,\n",
       "    27.750624389048756,\n",
       "    33.499888333705556,\n",
       "    32.9998785421137]}},\n",
       " 'wifi': {'fullAlign': {'rtc_alarm': [39, 46, 45, 59, 18],\n",
       "   'drain': [38.25286365187616,\n",
       "    42.650794252568524,\n",
       "    40.002814086852084,\n",
       "    39.50334406780685,\n",
       "    42.87903313491913]},\n",
       "  'align': {'rtc_alarm': [], 'drain': []},\n",
       "  'paper': {'rtc_alarm': [], 'drain': []},\n",
       "  'origin': {'rtc_alarm': [85, 54, 51, 42, 64, 40, 49, 88, 68, 48],\n",
       "   'drain': [38.752489309209096,\n",
       "    37.24912826692876,\n",
       "    41.50206645705901,\n",
       "    43.277306778429775,\n",
       "    37.749307929354636,\n",
       "    45.25167179787476,\n",
       "    48.74898439615841,\n",
       "    37.248680775889184,\n",
       "    40.74945667391101,\n",
       "    43.50129597610928]}},\n",
       " 'lte': {'fullAlign': {'rtc_alarm': [38, 33, 31, 32, 32],\n",
       "   'drain': [55.79260385221937,\n",
       "    53.24998151042308,\n",
       "    54.503459455690454,\n",
       "    57.50468024203081,\n",
       "    43.325924900463335]},\n",
       "  'align': {'rtc_alarm': [], 'drain': []},\n",
       "  'paper': {'rtc_alarm': [], 'drain': []},\n",
       "  'origin': {'rtc_alarm': [70, 30, 35, 41, 44, 35, 43, 41, 24],\n",
       "   'drain': [43.99895502481816,\n",
       "    58.00085390146022,\n",
       "    63.007062041537154,\n",
       "    51.254199996944195,\n",
       "    51.74954359777521,\n",
       "    50.505531057116464,\n",
       "    62.080350555492444,\n",
       "    55.72467880914297,\n",
       "    60.53164880443393]}}}"
      ]
     },
     "execution_count": 5,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "network_data"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 6,
   "id": "23a25070",
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "\n",
      "flight\n",
      "Align\n",
      "平均值: 31.61158593133975\n",
      "标准差: 2.9514327329184473\n",
      "中位数: 31.500404692699174\n",
      "Origin\n",
      "平均值: 32.361301210125\n",
      "标准差: 2.9586208296536287\n",
      "中位数: 32.9998785421137\n",
      "\n",
      "下降比例: -2.316703132291489%\n",
      "下降比例: -0.24295430705876955%\n",
      "下降比例: -4.543876873670701%\n",
      "\n",
      "wifi\n",
      "Align\n",
      "平均值: 40.65776983880455\n",
      "标准差: 1.8139127107008624\n",
      "中位数: 40.002814086852084\n",
      "Origin\n",
      "平均值: 41.40303883609239\n",
      "标准差: 3.633404155141698\n",
      "中位数: 41.12576156548501\n",
      "\n",
      "下降比例: -1.8000345342723225%\n",
      "下降比例: -50.076770068808315%\n",
      "下降比例: -2.730520811985066%\n",
      "\n",
      "lte\n",
      "Align\n",
      "平均值: 52.87532999216542\n",
      "标准差: 4.978427009127273\n",
      "中位数: 54.503459455690454\n",
      "Origin\n",
      "平均值: 55.20586930985786\n",
      "标准差: 5.961097168690375\n",
      "中位数: 55.72467880914297\n",
      "\n",
      "下降比例: -4.221542649046353%\n",
      "下降比例: -16.48471970435922%\n",
      "下降比例: -2.191523360116969%\n"
     ]
    }
   ],
   "source": [
    "import numpy as np\n",
    "\n",
    "def calculate_stats(arr):\n",
    "    mean = np.mean(arr)\n",
    "    std = np.std(arr)\n",
    "    median = np.median(arr)\n",
    "    return mean, std, median\n",
    "\n",
    "arr = [1, 2, 3, 4, 5]\n",
    "\n",
    "\n",
    "for j in range(len(networks)):\n",
    "    align_drain = network_data.get(networks[j]).get(strategies_list[0]).get(attri[1])\n",
    "    origin_drain = network_data.get(networks[j]).get(strategies_list[3]).get(attri[1])\n",
    "    mean, std, median = calculate_stats(align_drain)\n",
    "    print(\"\\n\"+networks[j])\n",
    "    print(\"Align\")\n",
    "    print(f'平均值: {mean}')\n",
    "    print(f'标准差: {std}')\n",
    "    print(f'中位数: {median}')\n",
    "    origin_mean, origin_std, origin_median = calculate_stats(origin_drain)\n",
    "    print(\"Origin\")\n",
    "    m = -(origin_mean - mean)/origin_mean * 100\n",
    "    n = -(origin_std -std)/origin_std * 100\n",
    "    q = -(origin_median -median)/origin_median * 100\n",
    "    print(f'平均值: {origin_mean}')\n",
    "    print(f'标准差: {origin_std}')\n",
    "    print(f'中位数: {origin_median}')\n",
    "    \n",
    "    print(f'\\n下降比例: {m}%')\n",
    "    print(f'下降比例: {n}%')\n",
    "    print(f'下降比例: {q}%')\n",
    "    \n",
    "    \n",
    "                                                                             "
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "id": "6b419fb7",
   "metadata": {},
   "outputs": [],
   "source": []
  }
 ],
 "metadata": {
  "kernelspec": {
   "display_name": "Python 3 (ipykernel)",
   "language": "python",
   "name": "python3"
  },
  "language_info": {
   "codemirror_mode": {
    "name": "ipython",
    "version": 3
   },
   "file_extension": ".py",
   "mimetype": "text/x-python",
   "name": "python",
   "nbconvert_exporter": "python",
   "pygments_lexer": "ipython3",
   "version": "3.8.16"
  }
 },
 "nbformat": 4,
 "nbformat_minor": 5
}
